home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / cstdio.arc / SRC.ARC / MEMALL.C < prev    next >
C/C++ Source or Header  |  1985-05-17  |  3KB  |  121 lines

  1. /*    memall.c - main memory allocator.
  2.     From K & R pages 173 - 177.
  3.     Entered - G. R. Mansfield.  84/07/31.
  4.     Ver 1.0-5517.
  5. */
  6.  
  7. #include <defstd.h>
  8.  
  9. #define NALLOC 128    /* units to allocate at once */
  10.  
  11. typedef int ALIGN;    /* forces alignment in 8086 */
  12.  
  13. union header {    /* free block header */
  14.     struct {
  15.         union header *ptr;    /* next free block */
  16.         unsigned size;    /* size of this free block */
  17.     } s;
  18.     ALIGN x;
  19. };
  20.  
  21. typedef union header HEADER;
  22.  
  23. /* local functions */
  24. static HEADER *moremem();
  25.  
  26. /* local data */
  27. static HEADER base;    /* empty list to get started */
  28. static HEADER *allocp = NULL;    /* last allocated block */
  29. static HEADER *moremem();
  30.  
  31. BYTE *malloc(nbytes)    /* general-purpose storage allocator */
  32. unsigned nbytes;
  33. {
  34.     register HEADER *p, *q;
  35.     register int nunits;
  36.     BYTE *bp;
  37.     int i, j;
  38.  
  39.     nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
  40.     if ((q = allocp) == NULL) {    /* no free list yet */
  41.         base.s.ptr = allocp = q = &base;
  42.         base.s.size = 0;
  43.     }
  44.     for (p = q->s.ptr;  ; q = p, p = p->s.ptr) {
  45.         if (p->s.size >= nunits) {    /* big enough */
  46.             if (p->s.size == nunits)    /* exactly */
  47.                 q->s.ptr = p->s.ptr;
  48.             else {    /* allocate tail end */
  49.                 p->s.size -= nunits;
  50.                 p += p->s.size;
  51.                 p->s.size = nunits;
  52.                 p->s.ptr = NULL;
  53.             }
  54.             allocp = q;
  55.             return((BYTE *)(p+1));
  56.         }
  57.         if (p == allocp)    /* wrapped around free list */
  58.             if ((p = moremem(nunits)) == NULL)
  59.                 return(NULL);    /* none left */
  60.     }
  61. }
  62.  
  63. BYTE *calloc(nelem, elsize)
  64. unsigned nelem, elsize;
  65. {
  66.     BYTE *p, *q;
  67.     unsigned n;
  68.  
  69.     n = nelem * elsize;
  70.     if ((p = q = malloc(n)) == NULL)
  71.         return(NULL);
  72.     while (n--)
  73.         *q++ = 0;
  74.     return(p);
  75. }
  76.  
  77. static HEADER *moremem(nu)    /* ask system for memory */
  78. unsigned nu;
  79. {
  80.     BYTE *sbrk();
  81.     register BYTE *cp;
  82.     register HEADER *up;
  83.     register int rnu;
  84.  
  85.     rnu = NALLOC * ((nu+NALLOC-1) / NALLOC);
  86.     cp = sbrk(rnu * sizeof(HEADER));
  87. /*printf("cp %04x\n", cp);*/
  88.     if ((int)cp == -1)    /* no space at all */
  89.         return(NULL);
  90.     up = (HEADER *)cp;
  91.     up->s.size = rnu;
  92.     free((BYTE *)(up+1));
  93.     return(allocp);
  94. }
  95.  
  96. free(ap)    /* put block ap in free list */
  97. BYTE *ap;
  98. {
  99.     register HEADER *p, *q;
  100.  
  101.     p = (HEADER *)ap - 1;    /* point to header */
  102. /*printf("free ap %04x p %04x, s %04x  ", p, p->s.ptr, p->s.size);*/
  103.     for (q=allocp; !(p > q && p < q->s.ptr); q=q->s.ptr)
  104.         if (q >= q->s.ptr && (p > q || p < q->s.ptr))
  105.             break;    /* at one end or other */
  106.  
  107.     if (p+p->s.size == q->s.ptr) {    /* join to upper nbr */
  108.         p->s.size += q->s.ptr->s.size;
  109.         p->s.ptr = q->s.ptr->s.ptr;
  110.     } else
  111.         p->s.ptr = q->s.ptr;
  112.     if (q+q->s.size == p) {    /* join to lower nbr */
  113.         q->s.size += p->s.size;
  114.         q->s.ptr = p->s.ptr;
  115.     } else
  116.         q->s.ptr = p;
  117.     allocp = q;
  118. /*printf("fp %04x p %04x, s %04x  ", p, p->s.ptr, p->s.size);
  119. printf("fq %04x p %04x, s %04x\n", q, q->s.ptr, q->s.size);*/
  120. }
  121.